﻿using Bright.Serialization;

namespace Geek.Server.Config.Luban
{
    /// <summary>
    /// Luban配置服务实现
    /// </summary>
    public sealed class LubanConfigurationService : IConfigurationService
    {
        private static readonly Logger LOGGER = LogManager.GetCurrentClassLogger();
        
        /// <summary>
        /// 配置实例字典
        /// </summary>
        private readonly Dictionary<Type, ILubanConfiguration> _configurations = new();
        
        /// <summary>
        /// luban配置表映射
        /// </summary>
        private readonly Dictionary<string, object> _lubanMapping = new();

        public LubanConfigurationService()
        {
            var assembly = GetType().Assembly;
            
            foreach (var type in assembly.GetTypes())
            {
                if (!type.IsClass)
                    continue;
                
                if (type.IsAbstract)
                    continue;

                if (!typeof(ILubanConfiguration).IsAssignableFrom(type))
                    continue;

                var instance = (ILubanConfiguration)Activator.CreateInstance(type);
                _configurations.Add(type, instance);
                _lubanMapping.Add(instance!.FullName, instance);
            }
        }

        public void Load()
        {
            foreach (var configuration in _configurations.Values)
            {
                var filePath = $"{System.Environment.CurrentDirectory}/Configurations/{configuration.AssetName}.bytes";
                LOGGER.Info("加载配置文件: {0}", filePath);
                if (!File.Exists(filePath))
                    throw new Exception($"配置文件不存在: {filePath}");
                
                configuration.LoadFromBytes(new ByteBuf(File.ReadAllBytes(filePath)));
            }

            foreach (var configuration in _configurations.Values)
                configuration.Resolve(_lubanMapping);
        }

        public T Get<T>() where T : class, IConfiguration
        {
            return _configurations.TryGetValue(typeof(T), out var configuration) ? (T)configuration : null;
        }
    }
}